<title>ReaLua Source Code</title>

<p style="text-align: center; font-size: small">
<a href="index.html">Return to Index</a></p>

<h1 style="text-align: center;">ReaLua Source Code</h1>


<p>ReaLua's
<a href="http://code.google.com/p/realua/source/checkout">source code</a> is hosted on
<a href="http://code.google.com/">Google Code.</a>  You can even
<a href="http://code.google.com/p/realua/source/browse/">browse</a> it.
</p>

<p>
It has been built with
<a href="http://www.microsoft.com/express/vc/">Microsoft Visual C++ 2008 Express Edition</a>,
which is free to download and use.
</p>

<p>The only thing not on ReaLua's Google Code pages that is necessary
to build ReaLua is the
<a href="http://luaforge.net/frs/download.php/3706/lua5_1_4_Win32_vc8_lib.zip">lua5.1.lib</a>,
which you put in the <code>trunk/src</code> directory.
</p>


<p>The workhorses of ReaLua are Signature Functions such as,</p>
<code><pre>static int fdouble2double(lua_State *L, double f(double) , char *fname )
{
	assertFunc(f, fname);

	double argu = luaL_checknumber(L, 1);
	double answer = f(argu);
	lua_pushnumber(L, answer);

	return 1;
}</pre></code>

Its first argument is the traditional <code>lua_State *</code> pointer.

Next is a function pointer to a
Reaper Extension API function that takes a <code>double</code>
and returns a <code>double</code>.  The function pointer has been initialized
and made available by
<code>glue.cpp</code> (see how <code>reaper_plugin_functions.h</code>
is included, and the function
<code>initFunctionPointers(reaper_plugin_info_t *rec)</code>).

Finally it is passed a text representation of the Reaper API function's
name for debugging.</p>

<p>A Signature Function gets the Lua-side arguments from Lua's stack,
calls the Reaper API function, and pushes the return values onto
Lua's stack.
</p>

<p>Associated maker-macros of the form
</p>
<code><pre>#define mkdouble2double(NAME) \
	static int f##NAME(lua_State *L) { return fdouble2double( L , NAME , #NAME); }
</pre></code>

glue the named Reaper API functions to the Signature Functions when invoked.

<code><pre>mkdouble2double(DB2SLIDER);</pre></code>

Should expand to
<code><pre>static int fDB2SLIDER(lua_State *L)
{
	return fdouble2double( L, DB2SLIDER, "DB2SLIDER" );
}</pre></code>


This function's name is the Reaper API function's name, with the
letter 'f' put at the beginning.  It is this function which is
called by Lua, and it is bound in the <code>luaL_reg reaReg []</code> struct.
The <code>DB2SLIDER</code> function pointer has been initialized in
<code>initFunctionPointers(reaper_plugin_info_t *rec)</code>.  It
calls the <code>fdouble2double</code> Signature Function.

</p>

<p>This way, to add a Reaper API function to ReaLua can be as easy as</p>
<ol>
<li>See if the Reaper API function has a signature that
matches an existing Signature Function</li>
<li>Add the Reaper API function's name to the
	<ol type="a">
		<li><code>sfp(...)</code> invocations in the
			<code>initFunctionPointers(reaper_plugin_info_t *rec)</code>
			function in	<code>glue.cpp</code> (initialize function pointer)</li>
		<li>the maker-macro invocations (call function, handle stack)</li>
		<li><code>rrentry(...)</code> invocations in the
			<code>luaL_reg reaReg []</code> struct in
			<code>glue.cpp</code> (bind with Lua)</li>
	</ol>
</li>
<li>
Build and enjoy.
</li>
</ol>
<p>That's just three lines of code.</p>
<p>
However, many Reaper API functions need special
handling, in that their signature may be unique, or they may
deserve some Lua-style treatment.  In these singleton cases,
the maker-macros don't save any work, so a Singleton Function
is the function hooked up to Lua (step 2a above).
You will need to write these functions yourself, but there
are plenty of examples to work from.
</p>

<p>The Singleton Function for the Reaper API Function <code>IsMediaExtension</code> is

<code><pre>// bool (*IsMediaExtension)(const char *ext, bool wantOthers);
// takes (string, bool) returns bool

static int fIsMediaExtension(lua_State *L)
{
	assertFunctionPointer( IsMediaExtension );

	char *ext = (char *) luaL_checkstring(L, 1);
	bool wantOthers = luaL_checkboolean(L, 2);
	bool answer = IsMediaExtension(ext, wantOthers);
	lua_pushboolean(L, answer);
	return 1;
}</pre></code>
</p>

<p>Its function pointer is set by
<code><pre>sfp(IsMediaExtension);</pre></code>

and it is bound to Lua with
<code><pre>rrentry(IsMediaExtension),</pre></code>

<p>
C++ code is handled in much the same way, but with the help
of the <a href="http://lua-users.org/wiki/LunaWrapper">Luna Wrapper</a>.
</p>

<p style="text-align: center; font-size: small">
<a href="index.html">Return to Index</a></p>
